package com.bicon.botu.mall.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.bicon.botu.core.base.common.Constants;
import com.bicon.botu.core.base.common.entity.BaseResult;
import com.bicon.botu.mall.order.common.OrderConstans;
import com.bicon.botu.mall.order.dto.*;
import com.bicon.botu.mall.order.entity.OrderChild;
import com.bicon.botu.mall.order.entity.OrderDetail;
import com.bicon.botu.mall.order.entity.OrderGoods;
import com.bicon.botu.mall.order.mapper.AfterSalesRecordsMapper;
import com.bicon.botu.mall.order.mapper.OrderChildMapper;
import com.bicon.botu.mall.order.mapper.OrderGoodsMapper;
import com.bicon.botu.mall.order.processor.handler.ProductRepertoryRpc;
import com.bicon.botu.mall.order.processor.handler.ProductRpc;
import com.bicon.botu.mall.order.service.IOrderChildService;
import com.bicon.botu.mall.order.service.IOrderDetailService;
import com.bicon.botu.mall.order.service.IOrderGoodsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.jxls.common.Context;
import org.jxls.expression.JexlExpressionEvaluator;
import org.jxls.transform.Transformer;
import org.jxls.util.JxlsHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 总订单Service
 *
 * @author dsp
 * @date 2018/5/14 12:58
 */
@Service
@Slf4j
public class OrderGoodsServiceImpl extends ServiceImpl<OrderGoodsMapper, OrderGoods> implements IOrderGoodsService {

    @Autowired
    private OrderGoodsMapper orderGoodsMapper;

    @Autowired
    private OrderChildMapper orderChildMapper;

    @Autowired
    private IOrderChildService iOrderChildService;

    @Autowired
    private IOrderDetailService iOrderDetailService;

    @Autowired
    private ProductRepertoryRpc productRepertoryRpc;

    @Autowired
    private AfterSalesRecordsMapper afterSalesRecordsMapper;

    @Autowired
    private ProductRpc productRpc ;

    @Autowired
    private AfterSalesRecordsServiceImpl afterSalesRecordsService;

    /**
     * 删除订单
     *
     * @param orderId 订单id
     * @return
     */
    @Override
    public boolean deleteOrder(String orderId, String userId) {
        List<OrderGoods> list = this.selectList(new EntityWrapper<OrderGoods>().eq("logic_delete", Constants.DEL_LOGIC_NORMAL).in("id", orderId));
        OrderGoods orderGoods = new OrderGoods();
        OrderChild orderChild = new OrderChild();
        orderGoods.setLogicDelete(OrderConstans.DEL_LOGIC_DELETE);
        orderChild.setLogicDelete(OrderConstans.DEL_LOGIC_DELETE);
        Integer orderGoodsOptNum = orderGoodsMapper.update(orderGoods, new EntityWrapper<OrderGoods>().eq("id", orderId));
        Integer orderChildOptNum = orderChildMapper.update(orderChild, new EntityWrapper<OrderChild>().eq("main_order_id", orderId));
        if (retBool(orderGoodsOptNum) && retBool(orderChildOptNum)) {
            String remark = "用户删除订单";
            iOrderChildService.insertOrderRecord(userId, list, remark);
            return true;
        } else {
            return false;
        }
    }

    /**
     * 取消订单
     *
     * @param orderId      订单id
     * @param cancelReason 取消订单原因
     * @return
     */
    @Override
    public boolean cancelOrder(String orderId, String cancelReason, String userId) {
        List<OrderGoods> orderGoodsList = this.selectList(new EntityWrapper<OrderGoods>().eq("logic_delete", Constants.DEL_LOGIC_NORMAL).in("id", orderId));
        //封装订单组对象 ，并执行修改操作
        OrderGoods orderGoods = new OrderGoods();
        orderGoods.setPayState(OrderConstans.ORDER_STATUS_6);
        orderGoods.setCancelOrder(cancelReason);
        List<OrderDetail> details = new OrderDetail().selectList(new EntityWrapper<OrderGoods>().eq("main_order_id", orderId).eq("logic_delete", 0));
        OrderVerifyDto verifyDto;
        List<OrderVerifyDto> list = new ArrayList<>();
        for (OrderDetail detail : details) {
            verifyDto = new OrderVerifyDto();
            verifyDto.setGoodsId(detail.getGoodsId());
            verifyDto.setGoodsNumber(detail.getGoodsNumber());
            list.add(verifyDto);
        }
        BaseResult baseResult = productRepertoryRpc.rollbackNum(JSONObject.toJSONString(list));
        if (baseResult.getCode() == Constants.RESPONSE_CODE_200) {
            if ((boolean) baseResult.getData()) {
                Integer orderGoodsOptNum = orderGoodsMapper.update(orderGoods, new EntityWrapper<OrderGoods>().eq("id", orderId));
                if (retBool(orderGoodsOptNum)) {
                    String remark = "用户取消订单";
                    iOrderChildService.insertOrderRecord(userId, orderGoodsList, remark);
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 我的订单模块 根据搜索框内容或状态查询数据
     *
     * @param page
     * @param userId
     * @param payState
     * @param condition
     * @return
     */
    @Override
    public Page<OrderGoodsDto> getPageByPayCondition(Page<OrderGoodsDto> page, String userId, Integer payState, String condition) {
        List<String> goodsIds = orderGoodsMapper.getPageByPayCondition(page, userId, payState, condition);
        if (goodsIds != null && !goodsIds.isEmpty()) {
            List<OrderGoodsDto> goodsDtoList = orderGoodsMapper.selectListByPayCondition(userId, payState, condition, goodsIds);
            if (goodsDtoList != null && goodsDtoList.size() > 0) {
                for (OrderGoodsDto orderGoodsDto : goodsDtoList) {
                    BigDecimal bigDecimal = new BigDecimal(0);
                    if (null != orderGoodsDto.getFreight()) {
                        bigDecimal = bigDecimal.add(orderGoodsDto.getFreight());
                    }
                    List<ChildAndDetailDto> childAndDetailDtos = orderGoodsDto.getChildAndDetailDtoList();
                    int childAmount = 0;
                    //售后中间状态
                    int quitStatus = 0;
                    //售后结束
                    int quitClose = 0;
                    for (ChildAndDetailDto detailDto : childAndDetailDtos) {
                        //处理售后状态代码,已同意为5,6为拒绝，7位撤销，所以567不属于售后正在进行的状态
                        if (StringUtils.isNotEmpty(detailDto.getQuitId()) && detailDto.getQuitStatus() < OrderConstans.ORDER_AFTER_SALES_STATUS_5 && quitStatus == 0) {
                            quitStatus = detailDto.getQuitType();
                        }
                        if (StringUtils.isNotEmpty(detailDto.getQuitId()) && detailDto.getQuitStatus().equals(OrderConstans.ORDER_AFTER_SALES_STATUS_5)) {
                            quitStatus = 3;
                        }
                        if (detailDto.getTotalPrice() != null) {
                            bigDecimal = bigDecimal.add(detailDto.getTotalPrice().subtract(detailDto.getDiscountMoney()));
                        } else {
                            bigDecimal = bigDecimal.add(new BigDecimal(0));
                        }
                        childAmount += detailDto.getGoodsNumber();
                    }
                    orderGoodsDto.setQuitStatus(quitStatus);
                    orderGoodsDto.setAmount(childAmount);
                    orderGoodsDto.setTotalMoney(bigDecimal);
                }
            }
            page.setRecords(goodsDtoList);
        }
        return page;
    }

    /**
     * 后台 多条件查询 订单及地址分页
     *
     * @param page
     * @param paramMap
     * @return
     */
    @Override
    public Page<OrderGoodsAndAddressDto> getOrderPageByCondition(Page<OrderGoodsAndAddressDto> page, Map<String, String> paramMap) {
        //获得所有订单及地址记录
        List<OrderGoodsAndAddressDto> orderGoodsAndAddressDtos = orderGoodsMapper.getOrderPageByCondition(page, paramMap);
        if (orderGoodsAndAddressDtos != null && orderGoodsAndAddressDtos.size() > 0) {
            //存储订单对象 用于修改订单已读、未读
            //List<OrderGoods> orderGoodsList = new ArrayList<>();
            List<String> orderGoodsIdList = new ArrayList<>();
            for (OrderGoodsAndAddressDto orderGoodsDto : orderGoodsAndAddressDtos) {
                BigDecimal bigDecimal = new BigDecimal(0);
                //获得子订单
                List<OrderChild> childAndDetails = iOrderChildService.selectList(new EntityWrapper<OrderChild>().eq("main_order_id",
                        orderGoodsDto.getId()));
                for (OrderChild orderChild : childAndDetails) {
                    if (orderChild.getTotalPrice() != null) {
                        bigDecimal = bigDecimal.add(orderChild.getTotalPrice());
                    } else {
                        bigDecimal = bigDecimal.add(new BigDecimal(0));
                    }
                    orderGoodsDto.setOrderType(orderChild.getOrderType());
                }
                orderGoodsDto.setTotalPrice(bigDecimal);
                /*if (StringUtils.isNotBlank(orderGoodsDto.getUserId())) {
                    orderGoodsDto.setUserName(iOrderChildService.checkName(orderGoodsDto.getUserId()));
                }
                //组装订单修改对象
                OrderGoods orderGoods = new OrderGoods();
                orderGoods.setId(orderGoodsDto.getId());
                orderGoods.setCheckStatus(OrderConstans.CHECK_STATUS_READ);
                orderGoodsList.add(orderGoods);*/
                orderGoodsIdList.add(orderGoodsDto.getId());
            }
            //更新已读未读状态
            /*if (orderGoodsList.size() > 0) {
                updateBatchById(orderGoodsList);
            }*/

            // 查询是否存在售后处理中的记录
            List<OrderGoodsAfterSaleStatisticsDto> statisticsList = this.afterSalesRecordsMapper.queryProcessingAfterSalesByOrderIds(orderGoodsIdList);
            if (CollectionUtils.isNotEmpty(statisticsList)) {
                for (int i = 0; i < orderGoodsAndAddressDtos.size(); i++) {
                    for (int j = 0; j < statisticsList.size(); j++) {
                        if (orderGoodsAndAddressDtos.get(i).getId().equals(statisticsList.get(j).getOrderGoodsId())) {
                            orderGoodsAndAddressDtos.get(i).setAfterSalesStatus(true);
                        }
                    }
                }
            }
        }
        page.setRecords(orderGoodsAndAddressDtos);
        return page;
    }

    /**
     * 修改优惠金额和运费
     *
     * @param orderGoodsId
     * @param discountMoney
     * @param freight
     * @return
     */
    @Override
    public boolean updateCost(String orderGoodsId, Double discountMoney, Double freight, String userId) {
        //优惠券总和
        BigDecimal discountTotal = new BigDecimal(0);
        //运费总和
        BigDecimal freightTotal = new BigDecimal(0);
        //查询主订单对象
        OrderGoods orderGoods = orderGoodsMapper.selectById(orderGoodsId);
        //查询子订单集合
        List<OrderChild> childList = orderChildMapper.selectList(new EntityWrapper<OrderChild>().eq("main_order_id", orderGoodsId));
        for (OrderChild child : childList) {
            //商品总价
            BigDecimal totalPrice = child.getTotalPrice();
            //优惠券价格
            BigDecimal disMoney = new BigDecimal(0);
            if (null != child.getDiscountMoney()) {
                disMoney = child.getDiscountMoney();
            }
            discountTotal = discountTotal.add(totalPrice.subtract(disMoney));
            freightTotal = freightTotal.add(child.getFreight());
        }
        //设置子订单优惠费用
        if (discountMoney != null && discountMoney >= 0) {
            for (OrderChild child : childList) {
                //商品总价
                BigDecimal totalPrice = child.getTotalPrice();
                //优惠券价格
                BigDecimal disMoney = new BigDecimal(0);
                if (null != child.getDiscountMoney()) {
                    disMoney = child.getDiscountMoney();
                }
                //商品总价减优惠金额 商品实付
                BigDecimal subtractMoney = totalPrice.subtract(disMoney);
                BigDecimal bigDecimal = subtractMoney.subtract(discountTotal.subtract(
                        new BigDecimal(discountMoney)).multiply(subtractMoney).divide(discountTotal,2,BigDecimal.ROUND_HALF_UP));
                child.setDiscountMoney(bigDecimal);
            }
            String remark = "修改优惠金额";
            List<OrderGoods> orderGoodsList = new ArrayList<>();
            orderGoodsList.add(orderGoods);
            iOrderChildService.insertOrderRecord(userId, orderGoodsList, remark);

        }
        //设置子订单运费
        if (freight != null && freight >= 0) {
          //  BigDecimal newfreightTotal = new BigDecimal(0);
            for (OrderChild child : childList) {
                //运费不为0的参与修改运费计算
                if (child.getFreight().floatValue() > OrderConstans.MONEY_0) {
                    BigDecimal upFreight = child.getFreight().subtract(new BigDecimal(freight));
                    BigDecimal bigDecimal = (child.getFreight().divide(freightTotal, 2, BigDecimal.ROUND_HALF_UP)).multiply(upFreight);
                    child.setFreight(child.getFreight().add(bigDecimal));
                }else if(child.getFreight().floatValue() == OrderConstans.MONEY_0){
                    child.setFreight(new BigDecimal(0));
                }
            }
            orderGoods.setFreight(new BigDecimal(freight));
            String remark = "修改运费";
            List<OrderGoods> orderGoodsList = new ArrayList<>();
            orderGoodsList.add(orderGoods);
            iOrderChildService.insertOrderRecord(userId, orderGoodsList, remark);
        }
        //修改订单组表及子订单表
        if (updateById(orderGoods) && iOrderChildService.updateBatchById(childList)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 根据商家ID 统计订单总数、待付款、待收货等状态对应数量
     *
     * @param storeId
     * @param payStateArray
     * @return
     */
    @Override
    public List<TotalPriceDTO> getOrderTotalByStoreId(String storeId, List<String> payStateArray) {
        return orderGoodsMapper.getOrderTotalByStoreId(storeId, payStateArray);
    }

    /**
     * 根据商家ID 统计提醒订单总数、待付款、待收货等状态对应数量
     *
     * @param storeId
     * @return
     */
    @Override
    public List<TotalPriceDTO> getWarnOrderTotalByStoreId(String storeId) {
        List<String> payStateArray = new ArrayList<>();
        payStateArray.add(String.valueOf(OrderConstans.ORDER_STATUS_1));
        payStateArray.add(String.valueOf(OrderConstans.ORDER_STATUS_2));
        List<TotalPriceDTO> result = orderGoodsMapper.getWarnOrderTotalByStoreId(storeId, payStateArray);

        // 查询售后状态的数据
        List<AfterSalesStatisticsDto> afterSalesStatistic = afterSalesRecordsService.statisticAfterSale(storeId);
        for (int i = 0; i < afterSalesStatistic.size(); i++) {
            if(afterSalesStatistic.get(i).getStatus() == 1){
                result.add(new TotalPriceDTO(3,afterSalesStatistic.get(i).getCount().intValue()));
            }
            if(afterSalesStatistic.get(i).getStatus() == 2){
                result.add(new TotalPriceDTO(4,afterSalesStatistic.get(i).getCount().intValue()));
            }

        }

        // 调用远程接口数据
        BaseResult<Map<String,Integer>> shelvesTotalResult = productRpc.shelvesTotal();
        log.info("调用商品上下架统计接口返回：{}", JSON.toJSON(shelvesTotalResult));
        if(shelvesTotalResult.getCode() == Constants.RESPONSE_CODE_200){
            result.add(new TotalPriceDTO(5,shelvesTotalResult.getData().get("stockout")));
            result.add(new TotalPriceDTO(6,shelvesTotalResult.getData().get("repertoryWarmTotal")));
            result.add(new TotalPriceDTO(7,shelvesTotalResult.getData().get("unReply")));
        }else{
            result.add(new TotalPriceDTO(5,0));
            result.add(new TotalPriceDTO(6,0));
            result.add(new TotalPriceDTO(7,0));
        }
        int count = 0;
        for (int i = 0; i < result.size(); i++) {
            count+=result.get(i).getAmount();
        }
        result.add(new TotalPriceDTO(-1,count));
        return result;
    }

    @Override
    public String exportOrder(Map<String, String> params, String sortType, String sortDirection,
                              HttpServletRequest request, HttpServletResponse response) {
        //查询订单数据
        List<OrderExportDto> orderExportDtoList = orderGoodsMapper.getOrderByCondition(params, sortType, sortDirection);

        // 订单总金额
        Map<String, BigDecimal> countAmountMap = new HashMap<>();

        for (int i = 0; i < orderExportDtoList.size(); i++) {
            BigDecimal countAmount = countAmountMap.get(orderExportDtoList.get(i).getOrderGoodsNo());
            if (countAmount == null) {
                countAmount = new BigDecimal("0.00");
                countAmount = countAmount.add(orderExportDtoList.get(i).getFreight());
            }
            countAmount = countAmount.add(orderExportDtoList.get(i).getCountAmount());
            countAmountMap.put(orderExportDtoList.get(i).getOrderGoodsNo(), countAmount);
        }
        for (int i = 0; i < orderExportDtoList.size(); i++) {
            BigDecimal countAmount = countAmountMap.get(orderExportDtoList.get(i).getOrderGoodsNo());
            orderExportDtoList.get(i).setTotalPrice(countAmount == null ? new BigDecimal("0.00") : countAmount);
        }

        InputStream stream = null;
        FileInputStream in = null;
        try {

            String templatePath = OrderConstans.EXCEL_TEMPLATE_BASE + File.separator + "order_template.xls";
            stream = getClass().getClassLoader().getResourceAsStream(templatePath);
            File targetFile = new File("order_template.xls");
            FileUtils.copyInputStreamToFile(stream, targetFile);
            in = new FileInputStream(targetFile);

            // 设定输出文件头与响应上下文类型
            String fileName = OrderGoodsServiceImpl.encodeFileName("订单列表.xls", request);
            response.setHeader("Content-disposition", "attachment; filename=" + fileName);
            response.setContentType("application/vnd.ms-excel");

            // 设置导出上下文内容
            Context context = new Context();
            context.putVar("orderList", orderExportDtoList);

            JxlsHelper jxlsHelper = JxlsHelper.getInstance();
            Transformer transformer = jxlsHelper.createTransformer(in, response.getOutputStream());
            JexlExpressionEvaluator evaluator = (JexlExpressionEvaluator) transformer.getTransformationConfig().getExpressionEvaluator();
            //添加自定义函数
            Map<String, Object> funcs = new HashMap<>();
            funcs.put("orderDto", new OrderExportDto());
            evaluator.getJexlEngine().setFunctions(funcs);
            jxlsHelper.processTemplate(context, transformer);
            response.flushBuffer();
            //调用RPC上传文件到文件系统
        } catch (FileNotFoundException e) {
            log.error("文件未找到", e);
        } catch (IOException e) {
            log.error("导出订单记录失败", e);
        } finally {
            if (stream != null) {
                try {
                    stream.close();
                } catch (IOException e) {
                    log.error("导出订单关闭流失败", e);
                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    log.error("导出订单关闭流失败", e);
                }
            }
        }
        return null;
    }

    /**
     * 根据订单ID集合 查询订单及地址组全对象
     *
     * @param orderGoodsIds 订单ID集合
     * @return
     */
    @Override
    public List<BatchDeliverGoodsDTO> getOrderGoodsAndAddressByIds(List<String> orderGoodsIds) {
        List<BatchDeliverGoodsDTO> goodsDTOList = orderGoodsMapper.getOrderGoodsAndAddressByIds(orderGoodsIds);
        for (BatchDeliverGoodsDTO entity : goodsDTOList) {
            //根据userId从Redis中获得UserName
            entity.setUserName(iOrderChildService.checkName(entity.getUserId()));
        }
        return goodsDTOList;
    }

    /**
     * 根据订单ID集合 查询订单及地址组全对象 及订单商品分类、商品总数量
     *
     * @param orderGoodsIds
     * @return
     */
    @Override
    public List<BatchDeliverGoodsDTO> gatPrintTrackingInfo(List<String> orderGoodsIds) {
        //获得商品和地址封状对象列表
        List<BatchDeliverGoodsDTO> goodsDTOList = orderGoodsMapper.getOrderGoodsAndAddressByIds(orderGoodsIds);
        for (BatchDeliverGoodsDTO entity : goodsDTOList) {
            StringBuffer stringBuffer = new StringBuffer("商品");
            int goodsAmount = 0;
            //获得子订单详细记录列表
            List<OrderDetail> details = iOrderDetailService.selectList(new EntityWrapper<OrderDetail>().eq("main_order_id", entity.getOrderGoodsId()));
            for (OrderDetail orderDetail : details) {
                goodsAmount += orderDetail.getGoodsNumber();
            }
            entity.setGoodsAmount(goodsAmount);
            entity.setClassficationName(stringBuffer.toString());
        }
        return goodsDTOList;
    }

    public static String encodeFileName(String fileName, HttpServletRequest request) throws UnsupportedEncodingException {
        String userAgent = request.getHeader("User-Agent");
        /* IE 8 至 IE 10 */
        if (userAgent.toUpperCase().contains("MSIE") || userAgent.contains("Trident/7.0")) {
            return URLEncoder.encode(fileName, "UTF-8");
        } else if (userAgent.toUpperCase().contains("MOZILLA") || userAgent.toUpperCase().contains("CHROME")) {
            return new String(fileName.getBytes(), "ISO-8859-1");
        } else {
            return URLEncoder.encode(fileName, "UTF-8");
        }
    }

    /**
     * 统计顾客支付数量
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return
     */
    @Override
    public List<CustomerStatisticsDTO> customersStatistics(String startTime, String endTime) {
        return orderGoodsMapper.customersStatistics(startTime, endTime);
    }

    /**
     * 已完成支付的订单数量
     *
     * @param startTime
     * @param endTime
     * @return
     */
    @Override
    public List<CustomerStatisticsDTO> paidStatistics(String startTime, String endTime) {
        return orderGoodsMapper.paidStatistics(startTime, endTime);
    }

    /**
     * 交易成功的订单数量
     *
     * @param startTime
     * @param endTime
     * @return
     */
    @Override
    public List<CustomerStatisticsDTO> doneOrderStatistics(String startTime, String endTime) {
        return orderGoodsMapper.doneOrderStatistics(startTime, endTime);
    }

    /**
     * 已完成支付的订单金额
     *
     * @param startTime
     * @param endTime
     * @return
     */
    @Override
    public List<CustomerStatisticsDTO> paidMoneyStatistics(String startTime, String endTime) {
        return orderGoodsMapper.paidMoneyStatistics(startTime, endTime);
    }

    /**
     * 交易成功的订单金额
     *
     * @param startTime
     * @param endTime
     * @return
     */
    @Override
    public List<CustomerStatisticsDTO> doneOrderMoneyStatistics(String startTime, String endTime) {
        return orderGoodsMapper.doneOrderMoneyStatistics(startTime, endTime);
    }

    @Override
    public List<OrderGoodsAfterSalesDto> queryOrderGoodsAfterSales(String orderGoodsId, Integer type) {
        return this.afterSalesRecordsMapper.queryGoodsAfterSalesByOrderId(orderGoodsId, type);
    }
}

